package com.mililoan.persist.system.impl;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.formula.functions.T;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;

import com.mililoan.common.dao.AbstractBaseDao;
import com.mililoan.model.system.Actor;
import com.mililoan.model.system.Function;
import com.mililoan.model.system.Menu;
import com.mililoan.persist.system.MenuDao;
import com.mililoan.persist.system.UserRightDao;


/**
 * 用户权限表操作实体类
 * 
 * @author mwei
 *
 */
@Repository("userRightDao")
public class UserRightDaoImpl extends AbstractBaseDao<T> implements UserRightDao {
	private static final Logger	LOGGER		= LoggerFactory.getLogger(UserRightDaoImpl.class);
	
	@Autowired
	private MenuDao				menuDao;

	/**
	 * 为用户添加角色
	 * 
	 * @param userId
	 *            用户ID
	 * @param actorId
	 *            角色
	 * @return
	 * @throws Exception
	 */
	public boolean addUserActor(Long userId, Integer actorId) throws Exception {
		LOGGER.info("======用户添加角色=======");
		boolean flag = false;
		if( actorId%100==0 ){
			flag = this.add(userId, "A", actorId, "1");
		} else {
			flag = this.add(userId, "F", actorId, "1");
		}
		return flag;
	}

	/**
	 * 为用户添加角色
	 * 
	 * @param userId
	 *            用户ID
	 * @param actorCodes
	 *            角色
	 * @return
	 * @throws Exception
	 */
	public boolean addUserActor(Long userId, ArrayList<Integer> actorCodes) throws Exception {
		for (int i = 0; i < actorCodes.size(); i++) {
			if (!this.addUserActor(userId, actorCodes.get(i))) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 为用户添加功能
	 * 
	 * @param userId
	 *            用户ID
	 * @param funCodes
	 *            角色
	 * @return
	 * @throws Exception
	 */
	public boolean addUserFun(Long userId, ArrayList<Integer> funCodes) throws Exception {
		if (null != funCodes && funCodes.size() > 0) {
			List<Menu> menuList	= new ArrayList<Menu>();
			Map<String, Integer> existMap = new HashMap<String, Integer>();
			int parentCode = 0;
			Boolean isDataAuth = false;
			//获取全部菜单
			if (menuList.size() == 0) {
				menuList = menuDao.getAllMenu();
			}			
			
			for (int i = 0; i < funCodes.size(); i++) {
				// 查询功能模块所属的父级菜单
				for (int j = 0; j < menuList.size(); j++) {
					if (funCodes.get(i).equals(menuList.get(j).getMenuId())) {
						parentCode = menuList.get(j).getParentMenu();
						if ("dataAuth".equals(menuList.get(j).getMenuUrl())) {
							isDataAuth = true;
							break;
						}
						isDataAuth = false;
					} else {
						isDataAuth = false;
					}
				}

				if (null != existMap && existMap.size() > 0) {
					if (parentCode != 0 && !existMap.containsKey(String.valueOf(parentCode))) {
						if (!this.add(userId, "F", parentCode, "1")) {
							return false;
						}
						existMap.put(String.valueOf(parentCode), parentCode);
					}
					if (!existMap.containsKey(funCodes.get(i))) {
						if (parentCode % 100 != 0) { // 说明是按钮或者数据权限
							if (!isDataAuth) {
								if (!this.add(userId, "B", funCodes.get(i), "1")) {
									return false;
								}
							} else {
								if (!this.add(userId, "D", funCodes.get(i), "1")) {
									return false;
								}
							}
							existMap.put(String.valueOf(funCodes.get(i)), funCodes.get(i));
						} else {
							if (!this.add(userId, "F", funCodes.get(i), "1")) {
								return false;
							}
							existMap.put(String.valueOf(funCodes.get(i)), funCodes.get(i));
						}
					}
				} else {
					if (parentCode != 0) {
						if (!this.add(userId, "F", parentCode, "1")) {
							return false;
						}
						existMap.put(String.valueOf(parentCode), parentCode);
					}

					if (parentCode % 100 != 0) { // 说明是按钮
						if (!this.add(userId, "B", funCodes.get(i), "1")) {
							return false;
						}
						existMap.put(String.valueOf(funCodes.get(i)), funCodes.get(i));
					} else {
						if (!this.add(userId, "F", funCodes.get(i), "1")) {
							return false;
						}
						existMap.put(String.valueOf(funCodes.get(i)), funCodes.get(i));
					}
				}

			}
		}
		return true;
	}

	/**
	 * 添加用户权限表
	 * 
	 * @param userId
	 * @param code
	 * @return
	 */
	public boolean add(final Long userId, final String ptype, final Integer code, final String flag)
			throws Exception {
		JdbcTemplate template = this.getJdbcTemplate();
		boolean pass = getUserFunc(userId, ptype, code, flag);
		if (!pass) {
			return true;
		}
		// 取得新的ID
//		final Integer newId = this.getSeqNextVal("SEQ_USER_FUNC_ID");
		String sql = "INSERT INTO SYS_USER_FUNC(USER_ID,PTYPE,CODE,FLAG) VALUES(?,?,?,?)";
		template.update(sql, new PreparedStatementSetter() {
			public void setValues(PreparedStatement arg0) throws SQLException {
				arg0.setLong(1, userId);
				arg0.setString(2, ptype);
				arg0.setInt(3, code);
				arg0.setString(4, flag);
			}
		});
		return true;
	}

	/**
	 * 
	 * @Title: getUserFunc
	 * @Description: 是否已有用户权限
	 * @author TangZengyan 2016年7月18日 下午5:11:52
	 * @param userId
	 * @param ptype
	 * @param code
	 * @param flag
	 * @return 有：返回false，没有：返回true
	 */
	@SuppressWarnings("rawtypes")
	public boolean getUserFunc(final Long userId, final String ptype, final Integer code, final String flag) {
		JdbcTemplate template = this.getJdbcTemplate();
		String sql = "SELECT * FROM SYS_USER_FUNC WHERE USER_ID=? AND PTYPE=? AND CODE=? AND FLAG=? ";
		List list = template.queryForList(sql, new Object[] { userId, ptype, code, flag });
		if (list == null || list.size() == 0) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * 删除用户所有角色和功能
	 * 
	 * @param userId
	 *            用户ID
	 * @return
	 */
	public boolean delUserActor(Long userId) {
		JdbcTemplate template = this.getJdbcTemplate();
		// 取得新的ID
		try {
			String sql = "DELETE FROM SYS_USER_FUNC WHERE USER_ID=?";
			template.update(sql, new Object[] { userId });
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error(e.getMessage());
			return false;
		}
		return true;
	}

	/**
	 * 获得一个用户的所有角色
	 * 
	 * @param userId
	 * @return
	 */
	public ArrayList<Actor> getActorsById(Long userId) {
		JdbcTemplate template = this.getJdbcTemplate();
		String sql = "SELECT * FROM SYS_ACTOR A WHERE A.ID IN (SELECT T.CODE FROM SYS_USER_FUNC T WHERE T.PTYPE='A' AND T.USER_ID=?) ORDER BY A.ID";
		final ArrayList<Actor> result = new ArrayList<Actor>();
		try {
			template.query(sql, new Object[] { userId }, new RowCallbackHandler() {
				public void processRow(ResultSet rs) throws SQLException {
					Actor actor = new Actor();
					actor.setId(rs.getInt("ID"));
					actor.setActorName(rs.getString("ACTOR_NAME"));
					actor.setDepCode(rs.getInt("DEP_CODE"));
					actor.setSummary(rs.getString("SUMMARY"));
					actor.setisvalid(rs.getString("ISVALID"));
					result.add(actor);
				}
			});
		} catch (Exception e) {
			LOGGER.error("--------查询用户所有角色时出错------------");
			LOGGER.error(e.getMessage());
			return null;
		}
		return result;
	}

	/**
	 * 获得一个用户的所有功能点
	 * 
	 * @param userId
	 * @return
	 */
	public ArrayList<Function> getFuncsById(Long userId) {
		JdbcTemplate template = this.getJdbcTemplate();
		String sql = "SELECT T.FLAG,F.* FROM (SELECT FLAG,CODE FROM SYS_USER_FUNC WHERE PTYPE IN ('F','B','D') AND USER_ID=? ) T LEFT JOIN SYS_FUNCTION F ON T.CODE=F.FUNC_CODE ";
		final ArrayList<Function> result = new ArrayList<Function>();
		try {
			template.query(sql, new Object[] { userId }, new RowCallbackHandler() {
				public void processRow(ResultSet rs) throws SQLException {
					Function function = new Function();
					function.setCode(rs.getInt("FUNC_CODE"));
					function.setName(rs.getString("FUNC_NAME"));
					function.setSummary(rs.getString("SUMMARY"));
					function.setFlag(rs.getString("FLAG"));
					result.add(function);
				}
			});
		} catch (Exception e) {
			e.printStackTrace();
			LOGGER.error("--------查询用户所有功能点时出错------------");
			LOGGER.error(e.getMessage());
			return null;
		}
		return result;
	}
}
